#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

#include "hash_map.h"

void map_init(hash_map_t *hm) {
	int i;
	memset(hm->objects, 0, hash_size * sizeof(void *));
	memset(hm->elems, 0, HASH_MAX_SIZE * sizeof(hash_obj_t));
	hm->list = NULL;
	for (i = 0; i < HASH_MAX_SIZE; ++i) {
		hm->elems[i].next_ob = hm->list;
		hm->list = &hm->elems[i];
	}
}

int map_insert(hash_map_t *hm, size_t key, void *data) {
	hash_obj_t *obj;
	if (hm->list) {
		obj = hm->list;
		hm->list = hm->list->next_ob;
	} else
		return 0;
	size_t idx = key % hash_size;
	obj->data = data;
	obj->key = key;
	obj->next_ob = hm->objects[idx];
	hm->objects[idx] = obj;
	return 1;
}

void *map_delete(hash_map_t *hm, size_t key) {
	size_t idx = key % hash_size;
	hash_obj_t *obj = hm->objects[idx];
	hash_obj_t *prev = NULL;
	while (obj) {
		if (obj->key == key) {
			if (prev)
				prev->next_ob = obj->next_ob;
			else
				hm->objects[idx] = NULL;
			obj->next_ob = hm->list;
			hm->list = obj;
			break;
		}
		prev = obj;
		obj = obj->next_ob;
	}
	if (!obj)
		return NULL;
	void *data = obj->data;
	return data;
}

void *map_get(hash_map_t *hm, size_t key) {
	size_t idx = key % hash_size;
	hash_obj_t *obj = hm->objects[idx];
	while (obj) {
		if (obj->key == key)
			return obj->data;
		obj = obj->next_ob;
	}
	return NULL;
}
